import {InboxOutlined} from '@ant-design/icons';
import { Icon } from '@umijs/max';
import {App, Button, Card, Col, Flex, GetProp, Image, Row, Select, Typography, Upload} from 'antd';
import type {UploadProps} from 'antd/es/upload';
import {useState} from 'react';
import Tesseract, {ImageLike, WorkerOptions} from 'tesseract.js';

const {Title} = Typography;
const {Dragger} = Upload;

type FileType = Parameters<GetProp<UploadProps, 'beforeUpload'>>[0];

const LangOptions = [
  {value: 'eng', label: 'English'},
  {value: 'chi_sim', label: 'Chinese'},
  {value: 'chi_tra', label: 'Chinese Traditional'},
  {value: 'jpn', label: 'Japanese'},
  {value: 'kor', label: 'Korean'},
  {value: 'fra', label: 'French'},
  {value: 'deu', label: 'German'},
  {value: 'spa', label: 'Spanish'},
  {value: 'ita', label: 'Italian'},
  {value: 'por', label: 'Portuguese'},
  {value: 'rus', label: 'Russian'},
  {value: 'ara', label: 'Arabic'},
  {value: 'pol', label: 'Polish'},
  {value: 'nld', label: 'Dutch'},
  {value: 'swe', label: 'Swedish'},
  {value: 'fin', label: 'Finnish'},
  {value: 'hun', label: 'Hungarian'},
  {value: 'ell', label: 'Greek'},
  {value: 'bul', label: 'Bulgarian'},
  {value: 'srp', label: 'Serbian'},
]

export default (): JSX.Element => {
  const {message} = App.useApp();
  const [loading, setLoading] = useState(false);
  const [file, setFile] = useState<File>();
  const [text, setText] = useState<string>();
  const [image, setImage] = useState<string>();
  const [langs, setLangs] = useState<string>('eng');

  const imageToBase64 = (file: FileType) => {
    const reader = new FileReader();
    reader.onload = function (e) {
      setImage(e.target.result as string)
    };
    reader.readAsDataURL(new Blob([file]));
  }

  const recognizeImage = (image: ImageLike, langs?: string | 'eng' | 'chi_tra', options?: Partial<WorkerOptions>) => {
    setLoading(true);
    Tesseract.recognize(image, langs || 'eng', {
      logger: (info) => console.log(info),
      ...options,
    })
      .then(({data}) => {
        console.log(data);
        message.success('识别成功');
        setText(data.text);
      })
      .finally(() => setLoading(false))
  }

  // @ts-ignore
  const props: UploadProps = {
    name: 'file',
    multiple: true,
    action: '#',
    beforeUpload(file) {
      setFile(file as File);
      imageToBase64(file);
      return false;
    },
    onDrop(e) {
      console.log('Dropped files', e.dataTransfer.files);
      imageToBase64(e.dataTransfer.files[0]);
      setFile(e.dataTransfer.files[0]);
    },
  };

  return (
    <Card>
      <Title>Text Recognizer</Title>
      <Row style={{marginBottom: 20}}>
        <Col span={6}>
          <Select
            options={LangOptions}
            onChange={(value) => setLangs(value)}
            defaultValue={langs}
            style={{width: '50%'}}
          />
        </Col>
        <Col span={12}>
          <Button type={'primary'} block onClick={() => recognizeImage(file as ImageLike, langs)}>开始识别</Button>
        </Col>
      </Row>
      <Dragger {...props} style={{marginBottom: 20}} maxCount={1}>
        <p className="ant-upload-drag-icon">
          <InboxOutlined/>
        </p>
        <p className="ant-upload-text">Click or drag file to this area to upload</p>
        <p className="ant-upload-hint">
          Support for a single or bulk upload. Strictly prohibited from uploading company data or other
          banned files.
        </p>
      </Dragger>
      <Row>
        <Col span={10}>
          <Card>
            <Image src={image}/>
          </Card>
        </Col>
        <Col span={2}>
          <Flex justify={'center'} align={'center'} style={{height: '100%'}}>
            <Icon icon="mdi:arrow-right-bold-outline" style={{fontSize: 50}}></Icon>
          </Flex>
        </Col>
        <Col span={12}>
          <Card loading={loading} style={{height: '100%'}}>
            {text}
          </Card>
        </Col>
      </Row>
    </Card>
  )
}
